task default: [
  'git:all',
  'gem:all'
]


namespace :gem do

  desc 'generate the gem file'
  task :generate do
    sh "gem build *.gemspec"
    gemfile = Dir['*.gem'].first
    mv gemfile, PARAMS[:next_step_dir]
  end

  desc 'generate the gem file'
  task all: [:generate]

end


namespace :git do

  desc 'commit all tracked files'
  task :commit do
    message = nil
    loop do
      print 'Commit message for tracked files: '
      message = gets.strip
      break unless message.index("'")
      puts "Please enter a message without single quotes (')."
    end
    sh "git commit -am '#{message}'"
  end

  desc 'add version tag'
  task :tag do
    sh "git tag v#{PARAMS[:gemspec].version}"
  end

  desc 'publish the git repository'
  task :push do
    sh 'git push -u origin master'
  end

  desc 'commit and tag the git repository'
  task all: [
    :commit,
    :tag,
    :push
  ]

end


# Task parameters ##################################
PARAMS = {
  next_step_dir: Dir['../4.*'].first,
  gemspec:   nil
}

# Capture gem specification by 'eval'ing the *.gemspec file
# using a fake Gem::Specification class
begin
  require 'ostruct'
  require 'pathname'

  module Gem
    # Fake Gem::Specification class
    class Specification
      def initialize 
        @spec = OpenStruct.new
        @spec.executables = []
        @spec.metadata = {}
        @spec.development_dependencies = []
        @spec.singleton_class.class_eval do
          def add_development_dependency *geminfo
            self.development_dependencies << geminfo
          end
        end

        yield @spec
        ::PARAMS[:gemspec] = @spec
      end
    end
  end

  def read_gemspec
    gemspec = Dir['../*/*.gemspec'].first
    return unless gemspec
    gemspec = Pathname.new(gemspec)
    return unless gemspec.file?
    gemspec = gemspec.read
    self.instance_eval gemspec
  end

  read_gemspec
end
